home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
scheme
/
boxer
/
boxer.lha
/
loader.lisp
< prev
next >
Wrap
Text File
|
1993-07-17
|
31KB
|
790 lines
;-*- Syntax: Zetalisp; Mode: Lisp; Package: Boxer;Base: 8; Fonts: CPTFONT -*-
;;; This is a machine independent binary loader for the BOXER system
;;;
;;; (C) Copyright 1984, 1985 Massachusetts Institute of Technology
;;;
;;; Permission to use, copy, modify, distribute, and sell this software
;;; and its documentation for any purpose is hereby granted without fee,
;;; provided that the above copyright notice appear in all copies and that
;;; both that copyright notice and this permission notice appear in
;;; supporting documentation, and that the name of M.I.T. not be used in
;;; advertising or publicity pertaining to distribution of the software
;;; without specific, written prior permission. M.I.T. makes no
;;; representations about the suitability of this software for any
;;; purpose. It is provided "as is" without express or implied warranty.
;;;
;;;
;;; +-Data--+
;;; This file is part of the | BOXER | system.
;;; +-------+
;;;
(DEFSUBST SIGN-EXTEND-IMMEDIATE-OPERAND (NUMBER)
(IF (LDB-TEST 1301 NUMBER) (- NUMBER %%BIN-OP-IM-ARG-SIZE) NUMBER))
(DEFINE-LOAD-COMMAND BIN-OP-NUMBER-IMMEDIATE (IGNORE VALUE)
(SIGN-EXTEND-IMMEDIATE-OPERAND VALUE))
(DEFINE-LOAD-COMMAND-FOR-EFFECT BIN-OP-FORMAT-VERSION (STREAM)
(LET ((VERSION (BIN-NEXT-VALUE STREAM)))
(COND ((= VERSION *VERSION-NUMBER*)
(SETQ *FILE-BIN-VERSION* VERSION))
((MEMBER VERSION *SUPPORTED-OBSOLETE-VERSIONS*)
(SETQ *FILE-BIN-VERSION* VERSION))
(T
(FERROR "Format version is ~D, which is not supported" VERSION)))))
(DEFINE-LOAD-COMMAND-FOR-EFFECT BIN-OP-FILE-PROPERTY-LIST (STREAM)
(LET* ((PACKAGE (PKG-FIND-PACKAGE 'BOXER))
(PLIST (BIN-NEXT-VALUE STREAM)))
;; first deal with the package
(SETQ *LOAD-PACKAGE* (GET (LOCF PLIST) ':PACKAGE))
;; now check for how bit arrays were dumped
(UNLESS (NULL (GET (LOCF PLIST) ':BIT-ARRAY-ORDER))
(SELECTQ (GET (LOCF PLIST) :BIT-ARRAY-ORDER)
(:ROW-MAJOR (SETQ *ROW-MAJOR-ORDER?* T))
(:COLUMN-MAJOR (SETQ *ROW-MAJOR-ORDER?* NIL))
(OTHERWISE (FERROR "~A Is An Unrecognized Bit Array Description. "
(GET (LOCF PLIST) :BIT-ARRAY-ORDER)))))))
(DEFINE-LOAD-COMMAND-FOR-EFFECT BIN-OP-EOF (IGNORE)
(*THROW 'BIN-LOAD-DONE T))
(DEFINE-LOAD-COMMAND BIN-OP-TABLE-STORE (STREAM)
(ENTER-BIN-LOAD-TABLE (BIN-NEXT-VALUE STREAM)))
(DEFINE-LOAD-COMMAND BIN-OP-TABLE-FETCH-IMMEDIATE (IGNORE INDEX)
(AREF *BIN-LOAD-TABLE* INDEX))
(DEFINE-LOAD-COMMAND BIN-OP-TABLE-FETCH (STREAM)
(AREF *BIN-LOAD-TABLE* (BIN-NEXT-BYTE STREAM)))
(DEFINE-LOAD-COMMAND-FOR-VALUE BIN-OP-SYMBOL (STREAM)
(INTERN (BIN-NEXT-VALUE STREAM)))
;;; for rel4, if it wants to be in the KEYWORD package, put it into the USER package
;;; since it was probably a colon name
(DEFINE-LOAD-COMMAND-FOR-VALUE BIN-OP-PACKAGE-SYMBOL (STREAM)
(LET* ((PACKAGE-STRING (BIN-NEXT-VALUE STREAM))
(PACKAGE (PKG-FIND-PACKAGE #-REL4 PACKAGE-STRING
#+REL4(IF (STRING-EQUAL PACKAGE-STRING "KEYWORD")
"USER"
PACKAGE-STRING)))
(PNAME (BIN-NEXT-VALUE STREAM)))
(FUNCALL #+3600 (SI:PKG-PREFIX-INTERN-FUNCTION PACKAGE) #-3600 'INTERN PNAME)))
(DEFINE-LOAD-COMMAND-FOR-VALUE BIN-OP-STRING-IMMEDIATE (STREAM LENGTH)
(LOAD-STRING STREAM LENGTH))
(DEFINE-LOAD-COMMAND-FOR-VALUE BIN-OP-STRING (STREAM)
(LOAD-STRING STREAM))
(DEFINE-LOAD-COMMAND-FOR-VALUE BIN-OP-SIMPLE-CONS (STREAM)
(LET ((THE-CAR (BIN-NEXT-VALUE STREAM))
(THE-CDR (BIN-NEXT-VALUE STREAM)))
(CONS THE-CAR THE-CDR)))
(DEFINE-LOAD-COMMAND-FOR-VALUE BIN-OP-LIST-IMMEDIATE (STREAM LENGTH)
(LOAD-LIST STREAM LENGTH))
(DEFINE-LOAD-COMMAND-FOR-VALUE BIN-OP-LIST (STREAM)
(LOAD-LIST STREAM))
(DEFINE-LOAD-COMMAND BIN-OP-POSITIVE-FIXNUM (STREAM)
(LOAD-FIXNUM STREAM))
(DEFINE-LOAD-COMMAND BIN-OP-NEGATIVE-FIXNUM (STREAM)
(- (LOAD-FIXNUM STREAM)))
(DEFINE-LOAD-COMMAND BIN-OP-POSITIVE-FLOAT (STREAM)
(LOAD-FLOAT STREAM NIL))
(DEFINE-LOAD-COMMAND BIN-OP-NEGATIVE-FLOAT (STREAM)
(LOAD-FLOAT STREAM T))
(DEFINE-LOAD-COMMAND-FOR-VALUE BIN-OP-ARRAY (STREAM LENGTH)
(LOAD-ARRAY STREAM LENGTH))
(DEFINE-LOAD-COMMAND BIN-OP-INITIALIZE-AND-RETURN-ARRAY (STREAM)
(INITIALIZE-ARRAY STREAM))
(DEFINE-LOAD-COMMAND BIN-OP-INITIALIZE-AND-RETURN-NUMERIC-ARRAY (STREAM)
(INITIALIZE-NUMERIC-ARRAY STREAM))
(DEFINE-LOAD-COMMAND BIN-OP-ROW-IMMEDIATE (STREAM LENGTH)
(LOAD-ROW STREAM LENGTH))
(DEFINE-LOAD-COMMAND BIN-OP-ROW (STREAM)
(LOAD-ROW STREAM))
(DEFINE-LOAD-COMMAND BIN-OP-NAME-ROW-IMMEDIATE (STREAM LENGTH)
(LOAD-NAME-ROW STREAM LENGTH))
(DEFINE-LOAD-COMMAND BIN-OP-NAME-ROW (STREAM)
(LOAD-NAME-ROW STREAM))
(DEFINE-LOAD-COMMAND BIN-OP-NAME-AND-INPUT-ROW-IMMEDIATE (STREAM LENGTH)
(LOAD-AND-CONVERT-TO-NAME-ROW STREAM LENGTH))
(DEFINE-LOAD-COMMAND BIN-OP-NAME-AND-INPUT-ROW (STREAM)
(LOAD-AND-CONVERT-TO-NAME-ROW STREAM))
;;; Box loading commands
(DEFINE-LOAD-COMMAND BIN-OP-DOIT-BOX (STREAM)
(LOAD-DOIT-BOX STREAM))
(DEFINE-LOAD-COMMAND BIN-OP-DATA-BOX (STREAM)
(LOAD-DATA-BOX STREAM))
(DEFINE-LOAD-COMMAND BIN-OP-PORT-BOX (STREAM)
(LOAD-PORT-BOX STREAM))
(DEFINE-LOAD-COMMAND BIN-OP-GRAPHICS-BOX (STREAM)
(LOAD-GRAPHICS-BOX STREAM))
(DEFINE-LOAD-COMMAND BIN-OP-TURTLE-BOX (STREAM)
(LOAD-TURTLE-BOX STREAM NIL))
(DEFINE-LOAD-COMMAND BIN-OP-TURTLE-BOX* (STREAM)
(LOAD-TURTLE-BOX STREAM T))
(DEFINE-LOAD-COMMAND BIN-OP-GRAPHICS-DATA-BOX (STREAM)
(LOAD-GRAPHICS-DATA-BOX STREAM))
(DEFINE-LOAD-COMMAND BIN-OP-SPRITE-BOX (STREAM)
(LOAD-SPRITE-BOX STREAM))
(DEFINE-LOAD-COMMAND BIN-OP-LL-BOX (STREAM)
(LOAD-LL-BOX STREAM))
(DEFINE-LOAD-COMMAND-FOR-EFFECT BIN-OP-END-OF-BOX (IGNORE)
(*THROW 'DONE-WITH-BOX T))
;;; Graphics loading commands
(DEFINE-LOAD-COMMAND-FOR-VALUE BIN-OP-GRAPHICS-SHEET (STREAM)
(LOAD-GRAPHICS-SHEET STREAM))
(DEFINE-LOAD-COMMAND BIN-OP-GRAPHICS-OBJECT (STREAM)
(LOAD-GRAPHICS-OBJECT STREAM))
(DEFINE-LOAD-COMMAND BIN-OP-TURTLE (STREAM)
(LOAD-TURTLE STREAM))
;;;The actual LOAD functions
(DEFUN LOAD-LIST (STREAM &OPTIONAL (LENGTH (BIN-NEXT-VALUE STREAM)))
(LET ((LIST (MAKE-LIST LENGTH)))
(LOOP FOR I FROM 0 BELOW LENGTH
FOR L = LIST THEN (CDR L)
DO (RPLACA L (BIN-NEXT-VALUE STREAM)))
LIST))
(DEFUN LOAD-STRING (STREAM &OPTIONAL (LENGTH (BIN-NEXT-VALUE STREAM)) &AUX STRING)
(SETQ STRING (MAKE-ARRAY LENGTH ':TYPE 'ART-STRING))
(LOOP FOR I FROM 0 BELOW LENGTH
WITH WORD
WHEN (ZEROP (\ I 2))
DO (ASET (LDB 0010 (SETQ WORD (BIN-NEXT-BYTE STREAM))) STRING I)
ELSE DO (ASET (LDB 1010 WORD) STRING I))
STRING)
(DEFUN LOAD-FIXNUM (STREAM &OPTIONAL (LENGTH (BIN-NEXT-VALUE STREAM)))
;; Kludge around to avoid having to create intermediate bignum masks inside DPB
(COND ((= LENGTH 1) (BIN-NEXT-BYTE STREAM))
#+3600
((= LENGTH 2) (SI:MAKE-32-BIT-NUMBER (BIN-NEXT-BYTE STREAM) (BIN-NEXT-BYTE STREAM)))
(T (LOOP FOR I FROM 0 BELOW LENGTH
FOR POS FROM 0 BY 16.
WITH WORD = 0
DO (SETQ WORD (DEPOSIT-BYTE WORD POS 16. (BIN-NEXT-BYTE STREAM)))
FINALLY (RETURN WORD)))))
(DEFUN LOAD-FLOAT (STREAM NEGATIVE)
(LET ((MANTISSA (BIN-NEXT-VALUE STREAM))
(EXPONENT (BIN-NEXT-VALUE STREAM)))
(MAKE-FLOAT-INTERNAL NEGATIVE MANTISSA EXPONENT)))
#-3600
(DEFUN MAKE-FLOAT-INTERNAL (NEGATIVE MANTISSA EXPONENT)
(IF (ZEROP MANTISSA)
0.0
(LET ((FLOAT (%ALLOCATE-AND-INITIALIZE DTP-EXTENDED-NUMBER DTP-HEADER ;Cons a flonum
(%LOGDPB SI:%HEADER-TYPE-FLONUM SI:%%HEADER-TYPE-FIELD 0) 0 NIL 2)))
(LET ((EXTRA-SIG (- (HAULONG MANTISSA) 37)))
(COND ((NOT (ZEROP EXTRA-SIG))
(SETQ MANTISSA (ASH MANTISSA (- EXTRA-SIG)))
(INCF EXPONENT EXTRA-SIG))))
(%P-DPB-OFFSET (LDB 3010 MANTISSA) 0010 FLOAT 0)
(%P-DPB-OFFSET (LDB 2010 MANTISSA) 2010 FLOAT 1)
(%P-DPB-OFFSET (LDB 0020 MANTISSA) 0020 FLOAT 1)
(%P-DPB-OFFSET (+ EXPONENT 2037) 1013 FLOAT 0)
(AND NEGATIVE (SETQ FLOAT (- FLOAT)))
FLOAT)))
#+3600
(DEFUN MAKE-FLOAT-INTERNAL (NEGATIVE MANTISSA EXPONENT)
(IF (ZEROP MANTISSA)
(%MAKE-POINTER SI:DTP-FLOAT 0)
(LET ((EXTRA-SIG (- (HAULONG MANTISSA) (1+ SI:%%FLOAT-FRACTION))))
(COND ((NOT (ZEROP EXTRA-SIG))
(SETQ MANTISSA (ASH MANTISSA (- EXTRA-SIG)))
(INCF EXPONENT EXTRA-SIG))))
(SI:%FLONUM (SI:%LOGDPB (IF NEGATIVE 1 0) SI:%%FLOAT-SIGN
(DPB (+ EXPONENT (+ 126. 24.)) SI:%%FLOAT-EXPONENT
(DPB MANTISSA SI:%%FLOAT-FRACTION 0))))))
(DEFUN TRANSPOSE-BIT-ARRAY (ARRAY)
"Returns a new array with width = heigth of arg and height - width of arg"
(MULTIPLE-VALUE-BIND (DIMS OPTS)
(DECODE-ARRAY ARRAY)
(LET ((RETURN-ARRAY (LEXPR-FUNCALL #'MAKE-ARRAY (REVERSE DIMS) OPTS)))
(COPY-ARRAY-CONTENTS ARRAY RETURN-ARRAY)
RETURN-ARRAY)))
(DEFUN LOAD-ARRAY (STREAM OPT-LENGTH)
(LET ((DIMENSIONS (BIN-NEXT-VALUE STREAM))
(OPTIONS (MAKE-LIST (* OPT-LENGTH 2)))
(PACKAGE PACKAGE))
(LOOP FOR I FROM 0 BELOW OPT-LENGTH
FOR L = OPTIONS THEN (CDDR L)
DO (LET ((KEYWORD (BIN-NEXT-VALUE STREAM)))
(SETF (CAR L) KEYWORD))
(SETF (CADR L) (BIN-NEXT-VALUE STREAM)))
#-3600
(LET ((TYPE (GET (LOCF OPTIONS) ':TYPE)))
(AND TYPE (LISTP TYPE) (EQ (CADR TYPE) 'SI:ART-BOOLEAN)
(SETF (CADR TYPE) 'ART-1B)))
(LEXPR-FUNCALL #'MAKE-ARRAY DIMENSIONS OPTIONS)))
(DEFUN INITIALIZE-ARRAY (STREAM)
(LET* ((ARRAY (BIN-NEXT-VALUE STREAM))
(LENGTH (BIN-NEXT-VALUE STREAM))
(Q-ARRAY (IF (= (#-LMITI ARRAY-#-DIMS #+LMITI ARRAY-RANK ARRAY) 1) ARRAY
(MAKE-ARRAY LENGTH ':DISPLACED-TO ARRAY))))
(DOTIMES (I LENGTH)
(ASET (BIN-NEXT-VALUE STREAM) Q-ARRAY I))
(OR (EQ ARRAY Q-ARRAY) (RETURN-ARRAY Q-ARRAY))
ARRAY))
(DEFUN INITIALIZE-NUMERIC-ARRAY (STREAM)
(LET* ((ARRAY (BIN-NEXT-VALUE STREAM))
(LENGTH (BIN-NEXT-VALUE STREAM))
(16-ARRAY (IF (AND (= (#-LMITI ARRAY-#-DIMS #+LMITI ARRAY-RANK ARRAY) 1)
#-TI(= (AREF #'ARRAY-BITS-PER-ELEMENT
(SI:ARRAY-TYPE-FIELD ARRAY)) 16.)
;;Explorers must have some function that correctly hacks this....
#+TI(= (CADR (ARRAY-ELEMENT-TYPE ARRAY)) 20000)
(NOT (ARRAY-HAS-LEADER-P ARRAY)))
ARRAY
(MAKE-ARRAY LENGTH ':TYPE 'ART-16B ':DISPLACED-TO ARRAY))))
(TELL STREAM :STRING-IN NIL 16-ARRAY 0 LENGTH)
(OR (EQ ARRAY 16-ARRAY) (RETURN-ARRAY 16-ARRAY))
(IF (EQ *ROW-MAJOR-ORDER?* *BIT-ARRAYS-ARE-ROW-MAJOR-ORDERED?*)
;; dumping order and current order match
ARRAY
(TRANSPOSE-BIT-ARRAY ARRAY))))
;;; loading boxer objects
;; them old compatibility blues
(DEFVAR %%OLD-FONT-NO-FIELD #O1010)
(DEFUN CONVERT-CHARACTER-FONT-FIELD (CHA)
(COND ((BOX? CHA) CHA)
((= *FILE-BIN-VERSION* *VERSION-NUMBER*) CHA)
((= *FILE-BIN-VERSION* 1)
(DPB (LDB %%OLD-FONT-NO-FIELD CHA) %%BOXER-FONT-NO-FIELD
(LDB %%BOXER-CHA-CODE-FIELD CHA)))
(T CHA)))
(DEFUN LOAD-ROW (STREAM &OPTIONAL (LENGTH (BIN-NEXT-VALUE STREAM)))
(LET ((NEW-ROW (MAKE-INSTANCE 'ROW)))
(LOOP FOR I FROM 1 TO LENGTH
DO (TELL NEW-ROW :APPEND-CHA
(CONVERT-CHARACTER-FONT-FIELD (BIN-NEXT-VALUE STREAM))))
NEW-ROW))
(DEFUN LOAD-NAME-ROW (STREAM &OPTIONAL (LENGTH (BIN-NEXT-VALUE STREAM)))
(LET* ((NAME (BIN-NEXT-VALUE STREAM))
(PREV-NAME-OR-FIRST-CHA (BIN-NEXT-VALUE STREAM))
(NEW-ROW (MAKE-INSTANCE 'NAME-ROW ':CACHED-NAME NAME)))
(LOOP
INITIALLY (UNLESS (STRINGP PREV-NAME-OR-FIRST-CHA)
(TELL NEW-ROW :APPEND-CHA
(CONVERT-CHARACTER-FONT-FIELD PREV-NAME-OR-FIRST-CHA)))
FOR I FROM (IF (STRINGP PREV-NAME-OR-FIRST-CHA) 1 2) TO LENGTH
DO (TELL NEW-ROW :APPEND-CHA (CONVERT-CHARACTER-FONT-FIELD (BIN-NEXT-VALUE STREAM))))
NEW-ROW))
;;;for compatibility with old BOXTOP files
(DEFUN LOAD-AND-CONVERT-TO-NAME-ROW (STREAM &OPTIONAL (LENGTH (BIN-NEXT-VALUE STREAM)))
(LET* ((NAME (BIN-NEXT-VALUE STREAM))
(NEW-ROW (MAKE-INSTANCE 'NAME-ROW ':CACHED-NAME NAME)))
(LOOP FOR I FROM 1 TO LENGTH
DO (TELL NEW-ROW :APPEND-CHA
(CONVERT-CHARACTER-FONT-FIELD (BIN-NEXT-VALUE STREAM))))
NEW-ROW))
;(DEFUN LOAD-NAME-AND-INPUT-ROW (STREAM &OPTIONAL (LENGTH (BIN-NEXT-VALUE STREAM)))
; (LET* ((NAME (BIN-NEXT-VALUE STREAM))
; (NEW-ROW (MAKE-INSTANCE 'NAME-AND-INPUT-ROW ':CACHED-NAME NAME)))
; (LOOP FOR I FROM 1 TO LENGTH
; DO (TELL NEW-ROW :APPEND-CHA (BIN-NEXT-VALUE STREAM)))
; NEW-ROW))
(DEFUN LOAD-DOIT-BOX (STREAM)
(LOAD-VANILLA-BOX (STREAM)
(LET* ((FIRST-ROW (BIN-NEXT-VALUE STREAM))
(DOIT-BOX (MAKE-INSTANCE 'DOIT-BOX ':NAME NAME ':DISPLAY-STYLE-LIST DISPLAY-LIST
':STATIC-VARIABLES-ALIST ENVIRONMENT
':LOCAL-LIBRARY LOCAL-LIBRARY
':FIRST-INFERIOR-ROW FIRST-ROW)))
;; we have to attach the first row to the box
(TELL (TELL DOIT-BOX :FIRST-INFERIOR-ROW) :SET-SUPERIOR-BOX DOIT-BOX)
;; if it has a name row, then we have to attach it to the box
(WHEN (NAME-ROW? NAME)
(TELL NAME :SET-SUPERIOR-BOX DOIT-BOX))
(*CATCH 'DONE-WITH-BOX
(LOOP DOING
(LET ((NEXT-STUFF (BIN-NEXT-VALUE STREAM)))
(COND ((ROW? NEXT-STUFF)
(TELL DOIT-BOX :APPEND-ROW NEXT-STUFF))
((OR (EQ NEXT-STUFF *EXPORT-ALL-VARIABLES-MARKER*)
(LISTP NEXT-STUFF))
(TELL DOIT-BOX :SET-EXPORTS NEXT-STUFF))))))
DOIT-BOX)))
(DEFUN LOAD-DATA-BOX (STREAM)
(LOAD-VANILLA-BOX (STREAM)
(LET* ((FIRST-ROW (BIN-NEXT-VALUE STREAM))
(DATA-BOX (MAKE-INSTANCE 'DATA-BOX ':NAME NAME ':DISPLAY-STYLE-LIST DISPLAY-LIST
':STATIC-VARIABLES-ALIST ENVIRONMENT
':FIRST-INFERIOR-ROW FIRST-ROW
':LOCAL-LIBRARY LOCAL-LIBRARY)))
(TELL (TELL DATA-BOX :FIRST-INFERIOR-ROW) :SET-SUPERIOR-BOX DATA-BOX)
;; if it has a name row, then we have to attach it to the box
(WHEN (NAME-ROW? NAME)
(TELL NAME :SET-SUPERIOR-BOX DATA-BOX))
(*CATCH 'DONE-WITH-BOX
(LOOP DOING
(LET ((NEXT-STUFF (BIN-NEXT-VALUE STREAM)))
(COND ((ROW? NEXT-STUFF)
(TELL DATA-BOX :APPEND-ROW NEXT-STUFF))
((OR (EQ NEXT-STUFF *EXPORT-ALL-VARIABLES-MARKER*)
(LISTP NEXT-STUFF))
(TELL DATA-BOX :SET-EXPORTS NEXT-STUFF))))))
DATA-BOX)))
(DEFUN LOAD-PORT-BOX (STREAM)
(LOAD-VANILLA-BOX (STREAM)
(LET* ((PORT (BIN-NEXT-VALUE STREAM))
(PORT-BOX (MAKE-INSTANCE 'PORT-BOX ':NAME NAME ':DISPLAY-STYLE-LIST DISPLAY-LIST
':STATIC-VARIABLES-ALIST ENVIRONMENT
':LOCAL-LIBRARY LOCAL-LIBRARY)))
(TELL PORT-BOX :SET-PORT-TO-BOX PORT)
;; if it has a name and input row, then we have to attach it to the box
(WHEN (NAME-ROW? NAME)
(TELL NAME :SET-SUPERIOR-BOX PORT-BOX))
(*CATCH 'DONE-WITH-BOX
(LET ((MAYBE-EXPORTS (BIN-NEXT-VALUE STREAM)))
(WHEN (OR (EQ MAYBE-EXPORTS *EXPORT-ALL-VARIABLES-MARKER*) (LISTP MAYBE-EXPORTS))
(TELL PORT-BOX :SET-EXPORTS MAYBE-EXPORTS)))
(BIN-NEXT-VALUE STREAM)
(FERROR "the port, ~S, was dumped with extraneous information" PORT-BOX)) ;here
PORT-BOX)))
(DEFUN HOOKUP-SPRITES (ROW GBOX)
(LOOP FOR BOX IN (TELL ROW :BOXES-IN-ROW)
WHEN (SPRITE-BOX? BOX)
DO (LET ((TURTLE (TELL BOX :ASSOCIATED-TURTLE)))
(TELL GBOX :ADD-GRAPHICS-OBJECT TURTLE)
(TELL TURTLE :DRAW))
(LOOP FOR SROW IN (TELL BOX :ROWS) DO
(HOOKUP-SPRITES SROW BOX))))
;;; pre-Jeremy-graphics have turtles in the alist and NO sprite boxes. We need to splice
;;; the turtles out of the binding list, give them sprite boxes and splice the sprite boxes
;;; into the binding list
(DEFUN CONVERT-TO-NEW-GRAPHICS (ALIST)
(LOOP WITH SPRITE-BOXES = NIL
FOR BINDING IN ALIST
INITIALLY (SETQ ALIST (DELQ (ASSQ :ORIGINAL-TURTLE ALIST) ALIST))
WHEN (TURTLE? (CDR BINDING))
DO (LET ((SB (MAKE-SPRITE-BOX (CDR BINDING))))
(PUSH SB SPRITE-BOXES)
(SETQ ALIST (DELQ (RASSQ (CDR BINDING) ALIST) ALIST))
(PUSH (CONS (CAR BINDING) SB) ALIST)
(TELL SB :SET-NAME (MAKE-NAME-ROW (NCONS (CAR BINDING)))))
FINALLY
(RETURN (VALUES ALIST (MAKE-ROW SPRITE-BOXES NIL)))))
(DEFUN LOAD-GRAPHICS-BOX (STREAM)
(IF (MEMBER *FILE-BIN-VERSION* '(1. 2.))
;; old version of graphics boxes
(LOAD-VANILLA-BOX (STREAM)
(LET* ((PICTURE (BIN-NEXT-VALUE STREAM))
;; we need do this to take care of dem old compatibility blues...
(GRAPHICS-SHEET (IF (GRAPHICS-SHEET? PICTURE)
PICTURE
(%MAKE-GRAPHICS-SHEET #-LMITI(ARRAY-DIMENSION-N 1 PICTURE)
#-LMITI(ARRAY-DIMENSION-N 2 PICTURE)
#+LMITI(ARRAY-DIMENSION PICTURE 1)
#+LMITI(ARRAY-DIMENSION PICTURE 2)
PICTURE
NIL)))
(GRAPHICS-BOX (MAKE-INSTANCE 'GRAPHICS-BOX ':NAME NAME
':DISPLAY-STYLE-LIST DISPLAY-LIST
':STATIC-VARIABLES-ALIST ENVIRONMENT
':LOCAL-LIBRARY LOCAL-LIBRARY
':GRAPHICS-SHEET GRAPHICS-SHEET)))
(SETF (GRAPHICS-SHEET-SUPERIOR-BOX GRAPHICS-SHEET) GRAPHICS-BOX)
;; if it has a name and unput row, then we have to attach it to the box
(WHEN (NAME-ROW? NAME)
(TELL NAME :SET-SUPERIOR-BOX GRAPHICS-BOX))
(*CATCH 'DONE-WITH-BOX
(LET ((MAYBE-EXPORTS (BIN-NEXT-VALUE STREAM)))
(WHEN (OR (EQ MAYBE-EXPORTS *EXPORT-ALL-VARIABLES-MARKER*)(LISTP MAYBE-EXPORTS))
(TELL GRAPHICS-BOX :SET-EXPORTS MAYBE-EXPORTS)))
(BIN-NEXT-VALUE STREAM) ;if this doesn't throw like it should we signal an error
(FERROR "the graphics box, ~S, was dumped with extraneous information"
GRAPHICS-BOX))
(MULTIPLE-VALUE-BIND (BINDINGS ROW)
(CONVERT-TO-NEW-GRAPHICS (TELL GRAPHICS-BOX :GET-STATIC-VARIABLES-ALIST))
(TELL GRAPHICS-BOX :SET-STATIC-VARIABLES-ALIST BINDINGS)
(TELL GRAPHICS-BOX :APPEND-ROW ROW)
(HOOKUP-SPRITES ROW GRAPHICS-BOX))
GRAPHICS-BOX))
;; Otherwise use the new version
(LOAD-VANILLA-BOX (STREAM)
(LET* ((PICTURE (BIN-NEXT-VALUE STREAM))
;; we need do this to take care of dem old compatibility blues...
(GRAPHICS-SHEET (IF (GRAPHICS-SHEET? PICTURE)
PICTURE
(%MAKE-GRAPHICS-SHEET #-LMITI(ARRAY-DIMENSION-N 1 PICTURE)
#-LMITI(ARRAY-DIMENSION-N 2 PICTURE)
#+LMITI(ARRAY-DIMENSION PICTURE 1)
#+LMITI(ARRAY-DIMENSION PICTURE 2)
PICTURE
NIL)))
(FIRST-ROW (BIN-NEXT-VALUE STREAM))
(GRAPHICS-BOX (MAKE-INSTANCE 'GRAPHICS-BOX ':NAME NAME
':DISPLAY-STYLE-LIST DISPLAY-LIST
':STATIC-VARIABLES-ALIST ENVIRONMENT
':FIRST-INFERIOR-ROW FIRST-ROW
':LOCAL-LIBRARY LOCAL-LIBRARY
':GRAPHICS-SHEET GRAPHICS-SHEET)))
(TELL (TELL GRAPHICS-BOX :FIRST-INFERIOR-ROW ) :SET-SUPERIOR-BOX GRAPHICS-BOX)
(HOOKUP-SPRITES (TELL GRAPHICS-BOX :FIRST-INFERIOR-ROW) GRAPHICS-BOX)
(SETF (GRAPHICS-SHEET-SUPERIOR-BOX GRAPHICS-SHEET) GRAPHICS-BOX)
;; if it has a name and unput row, then we have to attach it to the box
(WHEN (NAME-ROW? NAME)
(TELL NAME :SET-SUPERIOR-BOX GRAPHICS-BOX))
(*CATCH 'DONE-WITH-BOX
(LOOP DOING
(LET ((NEXT-STUFF (BIN-NEXT-VALUE STREAM)))
(COND ((ROW? NEXT-STUFF)
(TELL GRAPHICS-BOX :APPEND-ROW NEXT-STUFF)
(HOOKUP-SPRITES NEXT-STUFF GRAPHICS-BOX))
((OR (EQ NEXT-STUFF *EXPORT-ALL-VARIABLES-MARKER*)
(LISTP NEXT-STUFF))
(TELL GRAPHICS-BOX :SET-EXPORTS NEXT-STUFF))))))
GRAPHICS-BOX))))
(DEFUN LOAD-GRAPHICS-DATA-BOX (STREAM)
(LOAD-VANILLA-BOX (STREAM)
(LET* ((PICTURE (BIN-NEXT-VALUE STREAM))
;; we need do this to take care of dem old compatibility blues...
(GRAPHICS-SHEET (IF (GRAPHICS-SHEET? PICTURE)
PICTURE
(%MAKE-GRAPHICS-SHEET #-LMITI(ARRAY-DIMENSION-N 1 PICTURE)
#-LMITI(ARRAY-DIMENSION-N 2 PICTURE)
#+LMITI(ARRAY-DIMENSION PICTURE 1)
#+LMITI(ARRAY-DIMENSION PICTURE 2)
PICTURE
NIL)))
(FIRST-ROW (BIN-NEXT-VALUE STREAM))
(GRAPHICS-DATA-BOX (MAKE-INSTANCE 'GRAPHICS-DATA-BOX ':NAME NAME
':DISPLAY-STYLE-LIST DISPLAY-LIST
':STATIC-VARIABLES-ALIST ENVIRONMENT
':FIRST-INFERIOR-ROW FIRST-ROW
':LOCAL-LIBRARY LOCAL-LIBRARY
':GRAPHICS-SHEET GRAPHICS-SHEET)))
(TELL (TELL GRAPHICS-DATA-BOX :FIRST-INFERIOR-ROW ) :SET-SUPERIOR-BOX GRAPHICS-DATA-BOX)
(HOOKUP-SPRITES (TELL GRAPHICS-DATA-BOX :FIRST-INFERIOR-ROW) GRAPHICS-DATA-BOX)
(SETF (GRAPHICS-SHEET-SUPERIOR-BOX GRAPHICS-SHEET) GRAPHICS-DATA-BOX)
;; if it has a name and unput row, then we have to attach it to the box
(WHEN (NAME-ROW? NAME)
(TELL NAME :SET-SUPERIOR-BOX GRAPHICS-DATA-BOX))
(*CATCH 'DONE-WITH-BOX
(LOOP DOING
(LET ((NEXT-STUFF (BIN-NEXT-VALUE STREAM)))
(COND ((ROW? NEXT-STUFF)
(TELL GRAPHICS-DATA-BOX :APPEND-ROW NEXT-STUFF)
(HOOKUP-SPRITES NEXT-STUFF GRAPHICS-DATA-BOX))
((OR (EQ NEXT-STUFF *EXPORT-ALL-VARIABLES-MARKER*)
(LISTP NEXT-STUFF))
(TELL GRAPHICS-DATA-BOX :SET-EXPORTS NEXT-STUFF))))))
GRAPHICS-DATA-BOX)))
(DEFUN HOOKUP-SPRITE-INSTANCE-VARS (ALIST TURTLE)
(LOOP FOR PAIR IN ALIST
DO
(SELECTQ (CAR PAIR)
((BU:SHAPE)
(TELL TURTLE :ADD-SHAPE-BOX (CDR PAIR)))
((BU:SIZE)
(TELL TURTLE :ADD-SIZE-BOX (CDR PAIR)))
((BU:XPOS)
(TELL TURTLE :ADD-XPOS-BOX (CDR PAIR)))
((BU:YPOS)
(TELL TURTLE :ADD-YPOS-BOX (CDR PAIR)))
((BU:HEADING)
(TELL TURTLE :ADD-HEADING-BOX (CDR PAIR)))
((BU:PEN)
(TELL TURTLE :ADD-PEN-BOX (CDR PAIR)))
((BU:HOME)
(TELL TURTLE :ADD-HOME-BOX (CDR PAIR)))
((BU:SHOWN)
(TELL TURTLE :ADD-SHOWN-P-BOX (CDR PAIR)))) ))
(DEFUN LOAD-SPRITE-BOX (STREAM)
(LOAD-VANILLA-BOX (STREAM)
(LET* ((TURTLE (BIN-NEXT-VALUE STREAM))
(FIRST-ROW (BIN-NEXT-VALUE STREAM))
(SPRITE-BOX (MAKE-INSTANCE 'SPRITE-BOX ':NAME NAME
':DISPLAY-STYLE-LIST DISPLAY-LIST
':STATIC-VARIABLES-ALIST ENVIRONMENT
':FIRST-INFERIOR-ROW FIRST-ROW
':LOCAL-LIBRARY LOCAL-LIBRARY
':ASSOCIATED-TURTLE TURTLE)))
(TELL TURTLE :SET-SPRITE-BOX SPRITE-BOX)
(TELL (TELL SPRITE-BOX :FIRST-INFERIOR-ROW) :SET-SUPERIOR-BOX SPRITE-BOX)
(WHEN (NAME-ROW? NAME)
(TELL NAME :SET-SUPERIOR-BOX SPRITE-BOX))
(HOOKUP-SPRITE-INSTANCE-VARS ENVIRONMENT TURTLE)
(*CATCH 'DONE-WITH-BOX
(LOOP DOING
(LET ((NEXT-STUFF (BIN-NEXT-VALUE STREAM)))
(COND ((ROW? NEXT-STUFF)
(TELL SPRITE-BOX :APPEND-ROW NEXT-STUFF))
((OR (EQ NEXT-STUFF *EXPORT-ALL-VARIABLES-MARKER*)
(LISTP NEXT-STUFF))
(TELL SPRITE-BOX :SET-EXPORTS NEXT-STUFF))))))
SPRITE-BOX)))
(DEFUN LOAD-TURTLE-BOX-WITH-STATE (STREAM)
(LOAD-VANILLA-BOX (STREAM)
(LET* ((PICTURE (BIN-NEXT-VALUE STREAM))
(GRAPHICS-SHEET (IF (GRAPHICS-SHEET? PICTURE)
PICTURE
(%MAKE-GRAPHICS-SHEET (CADR DISPLAY-LIST)
(CADDR DISPLAY-LIST)
PICTURE
NIL)))
(IGNORE ;x-pos
(BIN-NEXT-VALUE STREAM))
(IGNORE ;y-pos
(BIN-NEXT-VALUE STREAM))
(IGNORE ;heading
(BIN-NEXT-VALUE STREAM))
(IGNORE ;sin-heading
(BIN-NEXT-VALUE STREAM))
(IGNORE ;cos-heading
(BIN-NEXT-VALUE STREAM))
(IGNORE ;pen-mode
(BIN-NEXT-VALUE STREAM))
(IGNORE ;shown-p
(BIN-NEXT-VALUE STREAM))
(TURTLE-BOX (MAKE-INSTANCE 'GRAPHICS-BOX ':NAME NAME
':DISPLAY-STYLE-LIST DISPLAY-LIST
':STATIC-VARIABLES-ALIST ENVIRONMENT
':GRAPHICS-SHEET GRAPHICS-SHEET))
; (TURTLE (MAKE-INSTANCE 'TURTLE ':X-POSITION X-POS ':Y-POSITION Y-POS
; ':HEADING HEADING ':SIN-HEADING SIN-HEADING
; ':COS-HEADING COS-HEADING ':PEN-MODE PEN-MODE
; ':SHOWN-P SHOWN-P))
)
LOCAL-LIBRARY ;the variable was bound but....
(SETF (GRAPHICS-SHEET-SUPERIOR-BOX GRAPHICS-SHEET) TURTLE-BOX)
;; if it has a name and input row, then we have to attach it to the box
; (TELL TURTLE-BOX :ADD-GRAPHICS-OBJECT TURTLE)
; (TELL TURTLE :DRAW)
(WHEN (NAME-ROW? NAME)
(TELL NAME :SET-SUPERIOR-BOX TURTLE-BOX))
(*CATCH 'DONE-WITH-BOX
(LET ((MAYBE-EXPORTS (BIN-NEXT-VALUE STREAM)))
(WHEN (OR (EQ MAYBE-EXPORTS *EXPORT-ALL-VARIABLES-MARKER*) (LISTP MAYBE-EXPORTS))
(TELL TURTLE-BOX :SET-EXPORTS MAYBE-EXPORTS)))
(BIN-NEXT-VALUE STREAM) ;if this doesn't throw like it should we signal an error
(FERROR "the graphics box, ~S, was dumped with extraneous information"
TURTLE-BOX))
TURTLE-BOX)))
(DEFUN LOAD-TURTLE-BOX-WITHOUT-STATE (STREAM)
(LOAD-VANILLA-BOX (STREAM)
(LET* ((WID (CADR DISPLAY-LIST))
(HEI (CADDR DISPLAY-LIST))
(GRAPHICS-SHEET (MAKE-GRAPHICS-SHEET WID HEI))
(TURTLE-BOX (MAKE-INSTANCE 'GRAPHICS-BOX ':NAME NAME
':STATIC-VARIABLES-ALIST ENVIRONMENT
':GRAPHICS-SHEET GRAPHICS-SHEET))
; (TURTLE (MAKE-TURTLE))
)
LOCAL-LIBRARY ;the variable was bound but....
(SETF (GRAPHICS-SHEET-SUPERIOR-BOX GRAPHICS-SHEET) TURTLE-BOX)
; (TELL TURTLE-BOX :ADD-GRAPHICS-OBJECT TURTLE)
(WHEN (NAME-ROW? NAME)
(TELL NAME :SET-SUPERIOR-BOX TURTLE-BOX))
(*CATCH 'DONE-WITH-BOX
(BIN-NEXT-VALUE STREAM) ;if this doesn't throw like it should we signal an error
(FERROR "the turtle box, ~S, was dumped with extraneous information"
TURTLE-BOX))
TURTLE-BOX)))
(DEFUN LOAD-TURTLE-BOX (STREAM RESTORE-P)
(IF RESTORE-P
(LOAD-TURTLE-BOX-WITH-STATE STREAM)
(LOAD-TURTLE-BOX-WITHOUT-STATE STREAM)))
(DEFUN LOAD-LL-BOX (STREAM)
(LOAD-VANILLA-BOX (STREAM)
(LET* ((FIRST-ROW (BIN-NEXT-VALUE STREAM))
(LL-BOX (MAKE-INSTANCE 'LL-BOX ':NAME NAME ':DISPLAY-STYLE-LIST DISPLAY-LIST
':STATIC-VARIABLES-ALIST ENVIRONMENT
':FIRST-INFERIOR-ROW FIRST-ROW
':LOCAL-LIBRARY LOCAL-LIBRARY)))
(TELL (TELL LL-BOX :FIRST-INFERIOR-ROW) :SET-SUPERIOR-BOX LL-BOX)
;; if it has a name and unput row, then we have to attach it to the box
(WHEN (NAME-ROW? NAME)
(TELL NAME :SET-SUPERIOR-BOX LL-BOX))
(*CATCH 'DONE-WITH-BOX
(LOOP DOING
(LET ((NEXT-STUFF (BIN-NEXT-VALUE STREAM)))
(COND ((ROW? NEXT-STUFF)
(TELL LL-BOX :APPEND-ROW NEXT-STUFF))
((OR (EQ NEXT-STUFF *EXPORT-ALL-VARIABLES-MARKER*)
(LISTP NEXT-STUFF))
(TELL LL-BOX :SET-EXPORTS NEXT-STUFF))))))
LL-BOX)))
(DEFUN LOAD-GRAPHICS-SHEET (STREAM)
(IF (MEMBER *FILE-BIN-VERSION* '(1. 2.))
(LET* ((WID (BIN-NEXT-VALUE STREAM))
(HEI (BIN-NEXT-VALUE STREAM))
(ARRAY (BIN-NEXT-VALUE STREAM))
(OBJECTS (BIN-NEXT-VALUE STREAM))
(SHEET (MAKE-GRAPHICS-SHEET-FROM-FILE WID HEI ARRAY ':WRAP)))
; (DOLIST (OBJECT OBJECTS)
; ;; we don't send the :SET-ASSOCIATED-SHEET message because the sheet has not yet been
; ;; connected to the box so it will lose when it tries to frob the environment
; (SETF (MINIMUM-GRAPHICS-OBJECT-ASSOCIATED-SHEET OBJECT) SHEET))
OBJECTS ;; the variable was bound but never.....
SHEET)
;; the new version instead
(LET* ((WID (BIN-NEXT-VALUE STREAM))
(HEI (BIN-NEXT-VALUE STREAM))
(ARRAY (BIN-NEXT-VALUE STREAM))
(DRAW-MODE (BIN-NEXT-VALUE STREAM))
(SHEET (MAKE-GRAPHICS-SHEET-FROM-FILE WID HEI ARRAY DRAW-MODE)))
SHEET)))
(DEFUN LOAD-GRAPHICS-OBJECT (STREAM)
(LET* ((FORM (BIN-NEXT-VALUE STREAM))
(PLIST (CDR FORM)))
(IF (NOT (MEMBER *FILE-BIN-VERSION* '(1. 2.)))
(INSTANTIATE-FLAVOR (CAR FORM) (LOCF PLIST) NIL)
;; we need to convert the Plist to the new representation of graphics objects...
(REMPROP (LOCF PLIST) :COS-HEADING)
(REMPROP (LOCF PLIST) :SIN-HEADING)
(REMPROP (LOCF PLIST) :NAME)
(PUTPROP (LOCF PLIST) (NCONS (GET (LOCF PLIST) :PEN-MODE)) :PEN)
(REMPROP (LOCF PLIST) :PEN-MODE)
(SETF (GET (LOCF PLIST) :X-POSITION) (NCONS (GET (LOCF PLIST) :X-POSITION)))
(SETF (GET (LOCF PLIST) :Y-POSITION) (NCONS (GET (LOCF PLIST) :Y-POSITION)))
(SETF (GET (LOCF PLIST) :HEADING) (NCONS (GET (LOCF PLIST) :HEADING)))
(SETF (GET (LOCF PLIST) :SHOWN-P) (NCONS (GET (LOCF PLIST) :SHOWN-P)))
(INSTANTIATE-FLAVOR (CAR FORM) (LOCF PLIST) NIL))))
(DEFUN LOAD-TURTLE (STREAM)
(LET* ((FORM (BIN-NEXT-VALUE STREAM))
(PLIST (CDR FORM)))
(INSTANTIATE-FLAVOR (CAR FORM) (LOCF PLIST) NIL)))
;;; Top level interface
(DEFUN LOAD-BINARY-BOX-INTERNAL (BOX PATHNAME)
(WITH-OPEN-FILE (FILESTREAM PATHNAME ':CHARACTERS NIL ':ERROR ':REPROMPT)
(LOADING-BIN-FILE (FILESTREAM 'BIN-LOAD-NEXT-COMMAND NIL)
(LET ((PACKAGE (PKG-FIND-PACKAGE 'BOXER)))
(BIN-LOAD-TOP-LEVEL FILESTREAM BOX)))))
(DEFUN BIN-LOAD-TOP-LEVEL (STREAM &OPTIONAL(BOX (MAKE-BOX ())) &AUX BOX-TO-RETURN)
;; presumably, the only thing left after the file's plist will be the top level box
(*CATCH 'BIN-LOAD-DONE
(SETQ BOX-TO-RETURN (BIN-NEXT-VALUE STREAM)) ;top level box
(LOOP DOING (BIN-NEXT-COMMAND STREAM)))
(LET ((PLIST (TELL BOX-TO-RETURN :RETURN-INIT-PLIST-FOR-FILING))
(FIRST-ROW (TELL BOX-TO-RETURN :FIRST-INFERIOR-ROW)))
;; we have to move the guts of BOX-TO-RETURN to the box which is already there
(TELL BOX :SEMI-INIT (LOCF PLIST))
(TELL BOX :SET-FIRST-INFERIOR-ROW FIRST-ROW)
(DOLIST (ROW (TELL BOX-TO-RETURN :ROWS))
(TELL ROW :SET-SUPERIOR-BOX BOX))
;; now we transfer the bindings to the already existing box
(TELL BOX :SET-STATIC-VARIABLES-ALIST (TELL BOX-TO-RETURN :GET-STATIC-VARIABLES-ALIST))
;; as well as the local library
(TELL BOX :SET-LOCAL-LIBRARY (TELL BOX-TO-RETURN :LOCAL-LIBRARY))
BOX))
(DEFUN DECODE-BIN-OPCODE (WORD)
(LET ((HIGH (LDB %%BIN-OP-HIGH WORD))
(LOW (LDB %%BIN-OP-LOW WORD)))
(IF (OR (= HIGH BIN-OP-COMMAND-IMMEDIATE) (= HIGH BIN-OP-BOX-IMMEDIATE))
LOW
(VALUES HIGH LOW))))
(DEFUN BIN-LOAD-START (STREAM &OPTIONAL SKIP-READING-PROPERTY-LIST)
(LET ((WORD (BIN-NEXT-BYTE STREAM)))
(OR (= WORD BIN-OP-FORMAT-VERSION)
(FERROR NIL "~A is not a BIN file" (FUNCALL STREAM ':TRUENAME)))
(FUNCALL STREAM ':UNTYI WORD)
(BIN-NEXT-COMMAND STREAM))
;; Read in the file property list before choosing a package.
(UNLESS SKIP-READING-PROPERTY-LIST
(LET ((WORD (BIN-NEXT-BYTE STREAM)))
(FUNCALL STREAM ':UNTYI WORD)
(AND (= WORD BIN-OP-FILE-PROPERTY-LIST)
(BIN-NEXT-COMMAND STREAM)))))
(DEFUN ENTER-BIN-LOAD-TABLE-INTERNAL (VALUE INDEX)
(AND ( INDEX (ARRAY-LENGTH *BIN-LOAD-TABLE*))
(ADJUST-ARRAY-SIZE *BIN-LOAD-TABLE* (* 2 (ARRAY-LENGTH *BIN-LOAD-TABLE*))))
(ASET VALUE *BIN-LOAD-TABLE* INDEX)
VALUE)
(DEFUN BIN-NEXT-BYTE (STREAM)
(SEND STREAM ':TYI "Unexpected end of file before logical end of binary data"))
(DEFUN BIN-LOAD-NEXT-COMMAND (STREAM)
(MULTIPLE-VALUE-BIND (INDEX EXTRA-ARG)
(DECODE-BIN-OPCODE (BIN-NEXT-BYTE STREAM))
(LET ((FUNCTION (BIN-OP-DISPATCH *BIN-OP-LOAD-COMMAND-TABLE* INDEX)))
(IF EXTRA-ARG
(FUNCALL FUNCTION STREAM EXTRA-ARG)
(FUNCALL FUNCTION STREAM)))))
(DEFUN BIN-NEXT-VALUE (STREAM)
(DO (VAL1 VAL2 VAL3) (NIL)
(MULTIPLE-VALUE (VAL1 VAL2 VAL3)
(BIN-NEXT-COMMAND STREAM))
(OR (EQ VAL1 *NO-VALUE-MARKER*)
(RETURN (VALUES VAL1 VAL2 VAL3)))))